﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Data;
using ERP.BusinessEntities.Base;
using System.Windows.Forms;
using ERP.BusinessEntities.Factory;
using Core.Component;
using ERP.DAL;
using ERP.BusinessEntities.Util;

namespace Core.Base
{
    public class SGVList<T> : BindingList<T>, ISGVList where T: BaseBusinessInfo
    {
        int _currentIndex = -1;
        Type ObjectType;
        String TableName = String.Empty;
        String ParentTable;
        String ColumnForeignToParentTable = String.Empty;
        String strPrefix = String.Empty;
        public BaseBusinessController Ctrl;

        String strModuleObjectID;

        BaseEntity entity;
        BaseModule module;

        public DataGridView GridView;

        public int CurrentIndex
        {
            get { return _currentIndex; }
            set
            {
                if (entity == null || String.IsNullOrEmpty(strModuleObjectID))
                {
                    _currentIndex = value;
                    return;
                }
                //if (value < 0 || value >= this.Count || value < 0)
                //{
                //    entity.ModuleObjects[strModuleObjectID] = null;
                //}
                //else if (_currentIndex != value)
                //{
                //entity.InvalidateObjectOnList(this[value], strTableName, strModuleObjectID);
                //entity.ModuleObjects[strModuleObjectID] = (T)this[value].Clone();
                //entity.module.UpdateModuleObjectBindingCtrls(entity.ModuleObjects[strModuleObjectID], strModuleObjectID);
                _currentIndex = value;
                UpdateCurrentIndexToAll();
                //}
            }
        }

        public void UpdateCurrentIndexToAll()
        {
            if (CurrentIndex >= 0 && CurrentIndex < this.Count)
            {
                entity.InvalidateObject(this[CurrentIndex]);
                entity.dicModuleObjects[strModuleObjectID] = (T)this[CurrentIndex].Clone();
                entity.module.UpdateBinding(strModuleObjectID);
            }
            else
            {
                object obj = BusinessFactory.CreateBusinessObject(TableName + "Info");
                entity.InvalidateObject(obj);
                entity.dicModuleObjects[strModuleObjectID] = (BaseBusinessInfo)obj;
                entity.module.UpdateBinding(strModuleObjectID);
            }
        }

        public SGVList()
        {
            ObjectType = typeof(T);
            TableName = ObjectType.Name.Substring(0, ObjectType.Name.Length - 4);
            strPrefix = TableName.Substring(0, TableName.Length - 1);
            Ctrl = (BaseBusinessController)BusinessFactory.CreateBusinessObject(TableName + "Controller");
            this.AllowNew = true;

            this.AddingNew += new AddingNewEventHandler(SGVList_AddingNew);
            this.ListChanged += new ListChangedEventHandler(SGVList_ListChanged);
        }

        protected override void OnAddingNew(AddingNewEventArgs e)
        {
            base.OnAddingNew(e);
        }

        void SGVList_ListChanged(object sender, ListChangedEventArgs e)
        {
        }

        void SGVList_AddingNew(object sender, AddingNewEventArgs e)
        {
        }



        public void InitList(BaseEntity _entity, String _strParentTable, String _strTable, String _strRelation)
        {
            this.TableName = _strTable;
            this.ParentTable = _strParentTable;
            this.ColumnForeignToParentTable = _strRelation;
            this.module = _entity.module;
            this.entity = _entity;
            module = entity.module;
            if (entity.dicLists.ContainsKey(_strTable) == false)
                entity.dicLists.Add(_strTable, this);

            if (Ctrl == null)
                Ctrl = (BaseBusinessController)BusinessFactory.CreateBusinessObject(TableName + "Controller");
        }

        public virtual void Binding(String strScreenName, String strGridName)
        {
            if (module == null) return;

            String strGridKeyName = SGVControlHelper.GetControlKeyName(strScreenName, strGridName);
            if (module.dicControls.ContainsKey(strGridKeyName) == false) return;

            if (module.dicControls[strGridKeyName] is SGVGridView == false) return;

            SGVGridView gridView = (SGVGridView)module.dicControls[strGridKeyName];
            GridView = gridView;
            gridView.AutoGenerateColumns = false;
            gridView.DataSource = this;
           
            gridView.Refresh();

            gridView.InitCellStyles();
        }

        public void Invalidate(DataSet ds)
        {
            if (ds == null || ds.Tables.Count == 0) return;
            this.Clear();
            foreach (DataRow dr in ds.Tables[0].Rows)
            {
                Object obj = Ctrl.GetObjectFromDataRow(dr);
                this.Add((T)obj);
            }
        }

        public void SaveList(bool isReCreate)
        {
            if (isReCreate == false) return;
            if (entity.MainObject == null) return;

            Object objMainID = DynamicObject.ReflectUtil.GetProperty(entity.MainObject, "ID");
            if (objMainID == null) return;

            int iMainObjectID = Convert.ToInt32(objMainID);
            if (iMainObjectID == 0) return;

            Ctrl.DeleteAllByParentID(ColumnForeignToParentTable, iMainObjectID);

            foreach (T item in this)
            {
                AppContext.SetProperty(item, ColumnForeignToParentTable, iMainObjectID);
                Ctrl.CreateObject(item);
            }
        }


        public void DeleteList()
        {
            Object objMainID = DynamicObject.ReflectUtil.GetProperty(entity.MainObject, "ID");
            if (objMainID == null) return;

            int iMainObjectID = Convert.ToInt32(objMainID);
            if (iMainObjectID == 0) return;

            Ctrl.DeleteAllByParentID(ColumnForeignToParentTable, iMainObjectID);
        }


        public object GetAt(int iIndex)
        {
            if(iIndex >= 0 && iIndex < this.Count)
                return this[iIndex];
            return null;
        }


        public void InvalidateObject(object obj)
        {
            if (obj == null || obj is BaseBusinessInfo == false) return;

            String strTableName = Host.sqlDbUtil.GetTableNameFromBusinessObject((BaseBusinessInfo)obj);

            if (ParentTable != strTableName || String.IsNullOrEmpty(ColumnForeignToParentTable)) return;

            Object objID = AppContext.GetProperty(obj, "ID");
            if (obj == null) return;

            int iObjID = Convert.ToInt32(objID);

            DataSet ds = Ctrl.GetAllObjectByColumnValue(ColumnForeignToParentTable, iObjID);

            this.Invalidate(ds);

        }


        public DataGridView GetGridView()
        {
            return GridView;
        }
    }
}
